package Parse;
import ErrorMsg.ErrorMsg;

%% 

%implements Lexer
%function nextToken
%type java_cup.runtime.Symbol
%char

%{
StringBuffer string = new StringBuffer();
int count;

private void newline() {
  errorMsg.newline(yychar);
}

private void err(int pos, String s) {
  errorMsg.error(pos,s);
}

private void err(String s) {
  err(yychar,s);
}

private java_cup.runtime.Symbol tok(int kind, Object value) {
    return new java_cup.runtime.Symbol(kind, yychar, yychar+yylength(), value);
}

private ErrorMsg errorMsg;

Yylex(java.io.InputStream s, ErrorMsg e) {
  this(s);
  errorMsg=e;
}

%}

%eofval{
	{
	if (yystate()==COMMENT) err("comment symbol don't match");
	if (yystate()==STRING) err("String presentation error!");
	if (yystate()==STRING1) err("String presentation error!");
	 return tok(sym.EOF, null);
        }
%eofval}       

LineTerminator = \n|\r|\r\n|\n\r

%state STRING
%state COMMENT
%state STRING1

%%
<YYINITIAL> " "	{}
<YYINITIAL> \r|\f|\t {}
<YYINITIAL> \"	{string.setLength(0);yybegin(STRING);}
<YYINITIAL> "/*" {count=1;yybegin(COMMENT);}
<YYINITIAL> "*/" {err("comment symbol don't match!");}
<YYINITIAL> \n	{newline();}
<YYINITIAL> ","	{return tok(sym.COMMA, null);}
<YYINITIAL> ";" {return tok(sym.SEMICOLON,null);}
<YYINITIAL> ":" {return tok(sym.COLON,null);}
<YYINITIAL> "function" {return tok(sym.FUNCTION,null);}
<YYINITIAL> "/" {return tok(sym.DIVIDE,null);}
<YYINITIAL> "else" {return tok(sym.ELSE,null);}
<YYINITIAL> ">" {return tok(sym.GT,null);}
<YYINITIAL> "|" {return tok(sym.OR,null);}
<YYINITIAL> "do" {return tok(sym.DO,null);}
<YYINITIAL> ">=" {return tok(sym.GE,null);}
<YYINITIAL> "<" {return tok(sym.LT,null);}
<YYINITIAL> "<=" {return tok(sym.LE,null);}
<YYINITIAL> "-" {return tok(sym.MINUS,null);}
<YYINITIAL> "array" {return tok(sym.ARRAY,null);}
<YYINITIAL> "type" {return tok(sym.TYPE,null);}
<YYINITIAL> "for" {return tok(sym.FOR,null);}
<YYINITIAL> "to" {return tok(sym.TO,null);}
<YYINITIAL> "of" {return tok(sym.OF,null);}
<YYINITIAL> "*" {return tok(sym.TIMES,null);}
<YYINITIAL> "in" {return tok(sym.IN,null);}
<YYINITIAL> "end" {return tok(sym.END,null);}
<YYINITIAL> ":=" {return tok(sym.ASSIGN,null);}
<YYINITIAL> "nil" {return tok(sym.NIL,null);}
<YYINITIAL> "." {return tok(sym.DOT,null);}
<YYINITIAL> "if" {return tok(sym.IF,null);}
<YYINITIAL> "while" {return tok(sym.WHILE,null);}
<YYINITIAL> "var" {return tok(sym.VAR,null);}
<YYINITIAL> "(" {return tok(sym.LPAREN,null);}
<YYINITIAL> ")" {return tok(sym.RPAREN,null);}
<YYINITIAL> "[" {return tok(sym.LBRACK,null);}
<YYINITIAL> "]" {return tok(sym.RBRACK,null);}
<YYINITIAL> "{" {return tok(sym.LBRACE,null);}
<YYINITIAL> "}" {return tok(sym.RBRACE,null);}
<YYINITIAL> "let" {return tok(sym.LET,null);}
<YYINITIAL> "+" {return tok(sym.PLUS,null);}
<YYINITIAL> "then" {return tok(sym.THEN,null);}
<YYINITIAL> "=" {return tok(sym.EQ,null);}
<YYINITIAL> "<>" {return tok(sym.NEQ,null);}
<YYINITIAL> "&" {return tok(sym.AND,null);}
<YYINITIAL> "break" {return tok(sym.BREAK,null);}
<YYINITIAL> [0-9]+ {return tok(sym.INT,new Integer(yytext()));}
<YYINITIAL> "error" {return tok(sym.error,null);}
<YYINITIAL> [a-zA-Z][:jletterdigit:]* {return tok(sym.ID,yytext());}
<YYINITIAL> [^] {err("illegal charater<"+yytext()+">!");}

<STRING> {
	\" {yybegin(YYINITIAL);return tok(sym.STRING,string.toString());System.out.println(string);}
	[^\n\t\"\\]+ {string.append(yytext());}
	\\[0-9][0-9][0-9]
		{int tmp=Integer.parseInt(yytext().substring(1, 4));
		if(tmp>255) err("exceed \\ddd"); else string.append((char)tmp);}
	\\t {string.append('\t');}
	\\n {string.append('\n');}
	\\\" {string.append('\"');}
	\\\\ {string.append('\\');}
	{LineTerminator} {err("String presentation error!");}
	\\ {yybegin(STRING1);}
}
<STRING1> {
\r|\f|\t|\n {}
" " {}
\\ {yybegin(STRING);}
\" {err("\\dont match");}
[^] {string.append(yytext());}
}
<COMMENT> {
	"/*" {count++;}
	"*/" {count--;if (count==0) {yybegin(YYINITIAL);}}
	[^] {}
}







